#ifndef __LIB_XSIP_H__
#define __LIB_XSIP_H__
#include <list>
#include <map>
#include "xobject.h"
#include "xrequest.h"
#include "xresponse.h"
#include "xtransport.h"
#include "xdialog.h"
#include "xcommand.h"
#include "xheader.h"
#include "xdatareceiver.h"
#include "xtransaction.h"
#include "xdgramtransport.h"
#include "xcontent.h"
#include "DelayQueue.hh"
using namespace std;

enum {
	XSIP_EVENT_CODE_SUCCESS = 0,
	XSIP_EVENT_CODE_FAILED = -0xdead,
	XSIP_EVENT_CODE_TIMEOUT = -0xefdd,
};

#define XSIP_VERSION "XSIP/2.0"
class XSIP_API XSIPEngine : public DelayQueue {
public:
	XSIPEngine();
	virtual ~XSIPEngine();
	void loop();
	void setMTU(int mtu);
	int getMTU();
	static XSIPEngine* getCurrentThreadEngine();

	static XSIPRequest* createRequest();
	
	int sendRequest(XSIPRequest* request);
	int sendResponse(XSIPResponse* response);

	int parseRawData(XSIPTransport* transport, char* data, int size);

	virtual void onCommand(XSIPCommand* command, XSIPTransaction* transaction, XSIPRequest* request) = 0;
	virtual void onInvite(XSIPTransaction* transaction, XSIPRequest* request) = 0;
	virtual void onReinvite(XSIPDialog* dialog, XSIPTransaction* transaction, XSIPRequest* request) = 0;
	virtual void onAck(XSIPDialog* dialog, XSIPTransaction* transaction) = 0;

	virtual XSIPCommand* onRequestHook(XSIPTransaction* transaction, XSIPRequest* request) = 0;

	friend class XSIPCommand;
	friend class Process;
	friend class XSIPCall;
	friend class XSIPDialog;
private:
	virtual void handleTimeout();
	void addTransaction(XSIPTransaction* transaction);
	void removeTransaction(XSIPTransaction* transaction);
	XSIPTransaction* lookupTransaction(XSIPHeader::header* transId);

	void addDialog(XSIPDialog* dialog);
	void removeDialog(XSIPDialog* dialog);
	XSIPDialog* lookupDialog(XSIPHeader::header* dialogId);

	static XSIPHeader::header* getHeader(char* data, int i);
	static void* getContentData(char* data, int size);
	static int getContentLength(char* data, int size);
private:
	list<XSIPTransaction*> m_transactionList;
	list<XSIPDialog*> m_dialogList;
	static list<XSIPEngine*> s_engineList;
	int m_threadId;
	int m_mtu;
};

#endif 
